/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package imperio.population;

import imperio.Imperio;
import imperio.Patrulha;
import imperio.Sistema;
import imperio.simulador.Simulador;
import java.util.ArrayList;

/**
 *
 * @author Bernardo
 */
public class Individuo {

       private double conforto;
       private double probSobrevivencia;
       private int tPoliciamento;
       private int tMinorante;
       private ArrayList<Patrulha> patrulhas;
       private ArrayList<Sistema> sistemas;
       private int numPatrulhas;
       
       
     /**Método construtor do individuo onde as patrulhas são criadas, os sistemas distribuidos entre as patrulhas e o cálculo do conforto é realizado
      
     */

    public Individuo() {
        this.patrulhas = new ArrayList<Patrulha>(); 
        this.sistemas = new ArrayList<Sistema>();                     
        this.sistemas = Imperio.getInstance().getSistemas();
        gerarPatrulhas();
        this.tPoliciamento = 0;
        this.tMinorante = 0;
        randSistemas();
        calcConforto();
    }
    
     /**Método construtor do individuo onde individuo gerado é uma cópia do individuo recebido como parâmetro.
      * 
      * @param individuo Individuo - Individuo a ser copiado.      
      */
    public Individuo(Individuo individuo) {
        this.patrulhas = new ArrayList<Patrulha>();               
        gerarPatrulhas();
        copiaLista(individuo.patrulhas);
        this.sistemas = Imperio.getInstance().getSistemas();        
    }
    
     /**Método para criação das patrulhas.
      
     */
    
    private void gerarPatrulhas() {
        for (int i = 0; i < Imperio.getInstance().getPatrulhas().size(); i++) {
            Patrulha patrulha = new Patrulha(i);
            patrulhas.add(patrulha);
        }
    }
    
    /**Método para o cálculo do tempo de policiamento do imperio pelas patrulhas.
      
     */

    public void calcTPoliciamento(){
        int temp;         
        for (int i = 0; i < patrulhas.size(); i++) {
            temp = 0;
            Patrulha patrulha = patrulhas.get(i);
            int linha, coluna;            
            linha = patrulha.getId();
            for (int j = 0; j < patrulhas.get(i).getSistemasPatrulhados().size(); j++) {                 
                coluna = patrulha.getSistemasPatrulhados().get(j).getId();                
                temp+= Simulador.Matriz[linha][coluna];
            }  
            if(temp > tPoliciamento)
            tPoliciamento = temp;            
        }       
    }

    /**Método para o cálculo do menor tempo de policiamento do imperio.
      
     */
    public void calcTMinorante(){
        int somatorio = 0;
        int menorValor = 0;
        
        for (int i = 0; i < sistemas.size(); i++) {
            menorValor = Simulador.Matriz[0][i];
            for (int j = 1; j < patrulhas.size(); j++) {
                int valorTemp = Simulador.Matriz[j][i];
                if(valorTemp < menorValor)
                    menorValor = valorTemp;
            }
            somatorio = somatorio + menorValor;
        }        
        //this.tMinorante = somatorio;    }
        this.tMinorante = somatorio/patrulhas.size();    }

    /**Método para o cálculo do conforto.
      
     */
    
    private void calcConforto(){
       calcTMinorante();
       calcTPoliciamento();       
       this.conforto = (double) tMinorante/tPoliciamento;          
       probSobrevivencia = (2/3)*conforto;
    }  

    public void setConforto(double conforto) {
        this.conforto = conforto;
    }

    public void settOtiPoliciamento(int tMinorante) {
        this.tMinorante = tMinorante;
    }

    public void settPoliciamento(int tPoliciamento) {
        this.tPoliciamento = tPoliciamento;
    }

    public void setSistemas(ArrayList<Sistema> sistemas) {
        this.sistemas = sistemas;
    }
    
    /**Método para o cálculo do conforto.
      
     */
    
     public void recalConforto(){
       calcTMinorante();
       calcTPoliciamento();       
       this.conforto = (double)tMinorante/tPoliciamento;
       probSobrevivencia = (2/3)*conforto;
    }
    
    public int gettPoliciamento() {
        return tPoliciamento;
    }

    public int gettMinorante() {
        return tMinorante;
    }
      

    public double getConforto() {
        return conforto;
    }

    public double getProbSobrevivencia() {
        return probSobrevivencia;
    }


    public ArrayList<Patrulha> getPatrulhas() {
        return patrulhas;
    }
    
    /**Método para distribuição uniforme e aleatória dos sistemas entre as patrulhas.
      
     */

    private void randSistemas() {
       int id = 0;
        for (int i = 0; i < sistemas.size(); i++) {            
            Sistema temp = sistemas.get(i);
            id = (int) (Math.random()* patrulhas.size());            
            patrulhas.get(id).getSistemasPatrulhados().add(temp);            
        }

    }
    
    /**Método para copia da distribuiçao das patrulhas.
      
     */

    private void copiaLista(ArrayList<Patrulha> listaOriginal) {
        for (int i = 0; i < listaOriginal.size(); i++) {
            //System.out.println(listaOriginal.size());            
            for (int j = 0; j < listaOriginal.get(i).getSistemasPatrulhados().size(); j++) {                
                this.patrulhas.get(i).getSistemasPatrulhados().add(listaOriginal.get(i).getSistemasPatrulhados().get(j));                    
            }           
        }
        
    }

}
